home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
xlib06p1.zip
/
XPLAIN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-15
|
6KB
|
231 lines
#include "xinternl.h"
#include <conio.h>
#include <mem.h>
/*==================================================================
XPLAIN.CPP contains the basic functions for pixel-resolution collision
detection in mode X.
These routines were written initially by Tiaan A Geldenhuys and
company and modified March 1995 by Victor B. Putz.
===================================================================*/
extern xScreenCoord_t TopClip;
extern xScreenCoord_t BottomClip;
int CollideX;
int CollideY;
void x_pbm_to_plain( /* Convert from planar bitmap to plain bitmap */
BYTE * pbSource,
BYTE * pbDest,
xColor_t ColorMask
)
{
int iNibbleWidth = *pbSource++;
int iHeight = *pbSource++;
//round up our nibble width to get byte width
int iByteWidth = ( iNibbleWidth + 1 ) / 2;
*pbDest++ = ( BYTE )iByteWidth;
*pbDest++ = ( BYTE )iHeight;
//store the location of the bitmap, since we come to it every plane
BYTE * pbDestRef = pbDest;
memset( pbDest, 0, iByteWidth * iHeight );
BYTE bHighPixMask = 0x80;
BYTE bLowPixMask = 0x08;
//now copy the pixels to bits
for ( int iPlaneCounter = 0; iPlaneCounter < 4; ++iPlaneCounter ) {
pbDest = pbDestRef;
for ( int iHeightCounter = 0; iHeightCounter < iHeight; ++iHeightCounter ) {
for ( int iWidthCounter = 0; iWidthCounter < iNibbleWidth; ++iWidthCounter ) {
int iTest = *pbSource++;
if ( iTest & ColorMask ) {
*pbDest |= bHighPixMask;
}
++iWidthCounter;
if ( iWidthCounter < iNibbleWidth ) {
iTest = *pbSource++;
if ( iTest & ColorMask ) {
*pbDest |= bLowPixMask;
}
}
++pbDest;
}
}
bHighPixMask >>= 1;
bLowPixMask >>= 1;
}
}
char x_check_collision_plain(
BYTE *VicStruct1,
int X1,
int Y1,
BYTE *VicStruct2,
int X2,
int Y2
)
{
//rearrange so that VicStruct1 is Leftmost
if ( X1 > X2 ) {
int iTemp = X2;
X2 = X1;
X1 = iTemp;
iTemp = Y2;
Y2 = Y1;
Y1 = iTemp;
BYTE * pbTemp = VicStruct2;
VicStruct2 = VicStruct1;
VicStruct1 = pbTemp;
}
//now that we're assured VicStruct1 is leftmost, get width and height
int iWidth1 = *VicStruct1++;
int iHeight1 = *VicStruct1++;
int iWidth2 = *VicStruct2++;
int iHeight2 = *VicStruct2++;
//First, just check for a rectangular collision
//get the offset into the first map of the second map
int iXOffset = X2 - X1;
//we know there's a collision; now let's turn the X offset from a pixel
//offset to a byte offset and get a "right shift" to see how many
//bits to the right we need to shift VicStruct1's data
int iRightShift = iXOffset & 0x07;
// iXOffset &= 0xfff8;
iXOffset >>= 3;
//if we're past the first map, return
if ( iXOffset > iWidth1 ) {
return 0;
}
//now check the Y part
int iYOffset = Y2 - Y1;
if ( iYOffset > iHeight1 ) {
return 0;
}
if ( ( iYOffset + iHeight2 ) < 0 ) {
return 0;
}
if ( iYOffset < 0 ) {
iYOffset *= -1;
}
//Well, now we get to the nitty gritty pixel-based detection.
//this will be messy code, because I don't have time to do it well.
//in most cases, the rectangular collision detection will reduce
//the time necessary. If it becomes an issue I'll look at it.
int iXToCheck = iWidth1 - iXOffset;
if ( iXToCheck > iWidth2 ) {
iXToCheck = iWidth2;
}
int iSkip1 = iWidth1 - iXToCheck;
int iSkip2 = iWidth2 - iXToCheck;
int iYToCheck = 0;
BYTE * pb1 = VicStruct1;
BYTE * pb2 = VicStruct2;
if ( Y1 <= Y2 ) {
iYToCheck = iHeight1 - iYOffset;
if ( iYToCheck > iHeight2 ) {
iYToCheck = iHeight2;
}
pb1 += iYOffset * iWidth1 + iXOffset;
pb2 += 0;
}
else {
iYToCheck = iHeight2 - iYOffset;
if ( iYToCheck > iHeight1 ) {
iYToCheck = iHeight1;
}
pb1 += iXOffset;
pb2 += iYOffset * iWidth2;
}
while( iYToCheck-- ) {
int iCheck1 = 0;
int iCheck2 = 0;
int iXCount = iXToCheck;
while( iXCount-- ) {
iCheck1 += *pb1++;
iCheck2 += *pb2++;
if ( ( iCheck1 << iRightShift ) & iCheck2 ) {
return 1;
}
iCheck1 <<= 8;
iCheck2 <<= 8;
}
pb1 += iSkip1;
pb2 += iSkip2;
}
return 0;
}
BYTE abFlipTable[] = {
0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
};
extern BYTE * pbVGABuffer;
extern int ScrnLogicalByteWidth;
extern BYTE abMirrorTable[];
extern WORD awTextMask[];
/*
Copy a VIC bitmap (variable size) from SRAM to VRAM.
Clips in Y direction only, and does not clip both top and bottom ( ie if
the top is clipped, bottom is not ).
*/
void x_put_plain(
int X,
int Y,
xPageHandle_t ScrnOffs,
BYTE * VicStruct,
xColor_t Color
)
{
BYTE * pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * Y ) + X / 4;
BYTE * pbSource = VicStruct;
int iByteWidth = *pbSource++;
int iHeight = *pbSource++;
int iSkip = ScrnLogicalByteWidth - ( iByteWidth * 2 );
//clip in Y direction
//clip top
int iHeightToPut = iHeight;
if ( Y < TopClip ) {
iHeightToPut = ( Y + iHeight ) - TopClip;
if ( iHeightToPut <= 0 ) {
return;
}
//now update pbSource to look at the new start
pbSource += ( TopClip - Y ) * iSkip;
pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * TopClip ) + X / 4;
}
else if ( ( Y + iHeight ) > BottomClip ) {
iHeightToPut = BottomClip - Y;
if ( iHeightToPut <= 0 ) {
return;
}
}
int iRotation = ( X & 3 );
outp( SC_INDEX, MAP_MASK );
int iTemp = 0;
for( int iRowCounter = 0; iRowCounter < iHeightToPut; ++iRowCounter ) {
for ( int iColumnCounter = 0; iColumnCounter < iByteWidth; ++iColumnCounter ) {
iTemp = *pbSource++;
iTemp = abMirrorTable[ iTemp ];
iTemp <<= iRotation;
//TEST STUFF!
outpw( SC_INDEX, awTextMask[ iTemp & 0x0f ] );
*pbDest++ = ( BYTE )Color;
outpw( SC_INDEX, awTextMask[ ( iTemp & 0xf0 ) >> 4 ] );
*pbDest++ = ( BYTE )Color;
outpw( SC_INDEX, awTextMask[ iTemp >> 8 ] );
*pbDest = ( BYTE )Color;
}
pbDest += iSkip;
}
}